#include <iostream>
#include <memory>

// 抽象产品A
class AbstractProductA{
public:
    virtual ~AbstractProductA() = default;
    virtual void use() const = 0;
};

// 具体产品 A1
class ConcreteProductA1 : public AbstractProductA{
public:
    void use() const override{
        std::cout << "Using Product A1" << std::endl; 
    }
};

// 具体产品A2
class ConcreteProductA2 : public AbstractProductA{
public:
    void use() const override{
        std::cout << "Using Product A2" << std::endl;
    }
};

// 抽象产品B
class AbstractProductB{
public:
    virtual ~AbstractProductB() = default;
    virtual void operation() const = 0;
};

// 具体产品B1
class ConcreteProductB1 : public AbstractProductB{
public:
    void operation() const override{
        std::cout << "Operation Product B1" << std::endl;
    }
};

// 具体产品B2
class ConcreteProductB2 : public AbstractProductB{
public:
    void operation() const override{
        std::cout << "Operation Product B2" << std::endl;
    }
};

// 抽象工厂接口
class AbstractFactory{
public:
    virtual ~AbstractFactory() = default;
    virtual std::unique_ptr<AbstractProductA> createProductA() const = 0;
    virtual std::unique_ptr<AbstractProductB> createProductB() const = 0;
};

// 具体工厂 （生产 A1 和 B1）
class ConcreteFactory1 : public AbstractFactory{
public:
    std::unique_ptr<AbstractProductA> createProductA() const override{
        return std::make_unique<ConcreteProductA1>();
    }
    std::unique_ptr<AbstractProductB> createProductB() const override{
        return std::make_unique<ConcreteProductB1>();
    }
};

// 具体工厂2 （生产 A2 和 B2）
class ConcreteFactory2 : public AbstractFactory{
public:
    std::unique_ptr<AbstractProductA> createProductA() const override{
        return std::make_unique<ConcreteProductA2>();
    }
    std::unique_ptr<AbstractProductB> createProductB() const override{
        return std::make_unique<ConcreteProductB2>();
    }
};

// 客户端代码
void clientCode(const AbstractFactory& factory){
    auto productA = factory.createProductA();
    auto productB = factory.createProductB();

    productA->use();
    productB->operation();
}

int main()
{
    // 使用第一个工厂生产 A1 + B1
    ConcreteFactory1 factory1;
    std::cout << "Client: Using Factory 1" << std::endl;
    clientCode(factory1);

    // 使用第二个工厂生产 A2 + B2
    ConcreteFactory2 factory2;
    std::cout << "Client: Using Factory 2" << std::endl;
    clientCode(factory2);


    return 0;
}